Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Xcode 16.0 support #942

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

Brett-Best
Copy link
Contributor

@Brett-Best Brett-Best commented Jun 10, 2024

Initial support for Xcode 16 which changed object versions and introduced a new attribute.

@@ -43,6 +43,10 @@ module ProjectSpecs
@root_object.minimized_project_reference_proxies.should == '0'
end

it 'returns the preferred project object version' do
@root_object.preferred_project_object_version.should == '73'
Copy link
Contributor Author

@Brett-Best Brett-Best Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we will want to check that this is in a set like the LAST_KNOWN_OBJECT_VERSION, my knowledge of the code doesn't extend that far unfortunately

@Brett-Best
Copy link
Contributor Author

Some of the other variable such as LAST_KNOWN_SWIFT_VERSION could do with updating as well

class Project
module Object
# This class represents a file system synchronized root group.
class PBXFileSystemSynchronizedRootGroup < AbstractObject
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Brett-Best thank you for working on this!

Unfortunately, from what I was able to gather, the implementation is a tiny bit incomplete.

  1. There are a few attributes that PBXFileSystemSynchronizedRootGroup has in common with PBXGroup, such as tabs/indent properties.

  2. There are also some properties unique to PBXFileSystemSynchronizedRootGroup that need to be added, such as explicitFileTypes, explicitFolders and exceptions (which require a further PBXFileSystemSynchronizedBuildFileExceptionSet object to represent).

Without this, I believe the representation will be incomplete and cause crashes.

I can recommend this article on synchronized groups by @pepicrft or this Tuist PR by the same for further info.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reply, yeah, it would be nice if the project file specification was published somewhere 🙃.
Yep, I expect if the project file uses these additional attributes that warnings/errors/crashes should be emitted.

I basically just added support to unblock the current utilization of the PBXFileSystemSynchronizedRootGroup in a project I was working on.

I may or may not end up updating this PR with the additional types, given CocoaPods is now in maintenance mode 😄.

Unfortunately, can't migrate off of CocoaPods to SPM yet because React Native 😢

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know, I don't think you're that far away! There are only a few things missing:

  • Copy attributes from PBXGroup to PBXFileSystemSynchronizedRootGroup: name, uses_tabs, indent_width, tab_width, wraps_lines
  • Add new attributes to PBXFileSystemSynchronizedRootGroup:
    • explicit_file_types (type Hash)
    • explicit_folders (type Array)
    • exceptions (relation, has_many of type PBXFileSystemSynchronizedBuildFileExceptionSet)
  • Add new type PBXFileSystemSynchronizedBuildFileExceptionSet with attributes:
    • target (relation, has_one AbstractTarget)
    • membership_exceptions (type Array)
    • public_headers (type Array)
    • private_headers (type Array)
    • additional_compiler_flags_by_relative_path (type Hash)
    • attributes_by_relative_path (type Hash)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reply, I've run into a new issue:

When a build configuration uses an xcconfig in the new folders the baseConfigurationReference is removed and replaced with baseConfigurationReferenceAnchor (PBXFileSystemSynchronizedRootGroup) and baseConfigurationReferenceRelativePath.

I managed to add that to the xcodeproj mostly fine but on the cocoapods side it needs some love at least in this section:
https://github.com/CocoaPods/CocoaPods/blob/85e6d43ca63f8acf0bb3f3d910e8ff1f6558a4e8/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb#L44-L66

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another issue is that my change adds file_system_synchronized_groups to all entries which is fine but when you edit the project file in Xcode, it removes the entries that are empty arrays.

Would you have any idea how I can stop Xcodeproj from adding empty array entries?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue above with the exceptions key of a PBXFileSystemSynchronizedRootGroup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Brett-Best I've looked at the rest of the uses of has_many - I think it's not possible to avoid initializing the empty ObjectList. Is this causing any issues? From what I know, many other things generated by Xcodeproj get modified by Xcode, and this has never been a concern.

In any case, great work! There are just a few more attributes to add, I think all of those are simple value types:

  • Copy attributes from PBXGroup to PBXFileSystemSynchronizedRootGroup: name, uses_tabs, indent_width, tab_width, wraps_lines
  • Add new attributes to PBXFileSystemSynchronizedRootGroup:
    • explicit_file_types (type Hash)
    • explicit_folders (type Array)
  • Add new attributes to PBXFileSystemSynchronizedBuildFileExceptionSet:
    • public_headers (type Array)
    • private_headers (type Array)
    • additional_compiler_flags_by_relative_path (type Hash)
    • attributes_by_relative_path (type Hash)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@igor-makarov along with the additional attributes listed, hopefully they don't also add empty groups.
Yes it is an issue, other things in the Pod project can sometimes change if you open it in Xcode to inspect the settings etc but this far less likely to be done on a day to day basis.
Whereas changing the settings of your own project is much more common.
Where I work atm we have churn of this getting added in / removed.
As a workaround I did come up with some regex but I couldn't get it to work on shell cause multiline hah...

@marcpalmer
Copy link

marcpalmer commented Sep 8, 2024

FYI fastlane's dependency on xcodeproj means that you can't build Xcode 16 projects that have the new PBXFileSystemSynchronizedRootGroup node type added e.g. if you add a widgets extension in Xcode 16 beta, it uses this node type and then you can no longer build with fastlane.

The workaround in this case is to remove that node from your project in Xcode 16, removing the references only, then open the project in Xcode 15, add the container node again/add the files back again, which creates the node as a PBXGroup, and then you can open the project in both 15 and 16 fine and xcodeproj can parse it fine and fastlane will build even with the Xcode 16 buildchain.

@drewolbrich
Copy link

FYI fastlane's dependency on xcodeproj means that you can't build Xcode 16 projects that have the new PBXFileSystemSynchronizedRootGroup node type added e.g. if you add a widgets extension in Xcode 16 beta, it uses this node type and then you can no longer build with fastlane.

I believe that more broadly, without similar workarounds, fastlane can't be used with any new project created with Xcode 16.

If you create a new iOS project with Xcode 16, its xcodeproj/project.pbxproj file will contain the string PBXFileSystemSynchronizedRootGroup.

@Brett-Best
Copy link
Contributor Author

I wonder if it would be possible to have Fastlane use https://github.com/tuist/XcodeProj 🤔

@pepicrft
Copy link

I wonder if it would be possible to have Fastlane use https://github.com/tuist/XcodeProj 🤔

That'll be tricky. Through the Ruby version of XcodeProj, tools like Fastlane can manipulate the object directly in memory through the various getters and setters available in Ruby objects defined by this library. If we adopt something like Tuist's XcodeProj, we'd have to use something like Ruby FFI, so the interaction between Fastlane (Ruby) and XcodeProj (Swift) would have to be through a set of functions that capture the various operations that the Ruby side of things has interest in doing.

@Westacular
Copy link

FYI fastlane's dependency on xcodeproj means that you can't build Xcode 16 projects that have the new PBXFileSystemSynchronizedRootGroup node type added e.g. if you add a widgets extension in Xcode 16 beta, it uses this node type and then you can no longer build with fastlane.

The workaround in this case is to remove that node from your project in Xcode 16, removing the references only, then open the project in Xcode 15, add the container node again/add the files back again, which creates the node as a PBXGroup, and then you can open the project in both 15 and 16 fine and xcodeproj can parse it fine and fastlane will build even with the Xcode 16 buildchain.

I haven't tested this, but I think there's a more simple fix: in Xcode 16, select the folder in the Project navigator, and go to Edit > Convert > To Group.

That should convert the PBXFileSystemSynchronizedRootGroup to a PBXGroup that Xcodeproj and Fastlane can handle.

@Levy4u
Copy link

Levy4u commented Sep 19, 2024

FYI fastlane's dependency on xcodeproj means that you can't build Xcode 16 projects that have the new PBXFileSystemSynchronizedRootGroup node type added e.g. if you add a widgets extension in Xcode 16 beta, it uses this node type and then you can no longer build with fastlane.
The workaround in this case is to remove that node from your project in Xcode 16, removing the references only, then open the project in Xcode 15, add the container node again/add the files back again, which creates the node as a PBXGroup, and then you can open the project in both 15 and 16 fine and xcodeproj can parse it fine and fastlane will build even with the Xcode 16 buildchain.

I haven't tested this, but I think there's a more simple fix: in Xcode 16, select the folder in the Project navigator, and go to Edit > Convert > To Group.

That should convert the PBXFileSystemSynchronizedRootGroup to a PBXGroup that Xcodeproj and Fastlane can handle.

"To Group" worked for me but I lost my app scheme. So I had to go to Product > Schemes > Autocreate Schemes Now, and it came back.

@mlight3
Copy link

mlight3 commented Oct 9, 2024

Any update or progress?

@Brett-Best
Copy link
Contributor Author

Brett-Best commented Oct 9, 2024

@mlight3 I haven't made any further improvements as this currently is sufficient for my needs.

@patrickhartling
Copy link

What is the likelihood of this PR being approved? I work on a large team with a large code base, and being able to use folders instead of groups could save us a lot of hassle. For example, our project file size could be reduced by more than 26,000 lines through the use of folders. However, we cannot make that move because Fastlane cannot build our code without this gem supporting folders.

@Brett-Best
Copy link
Contributor Author

Brett-Best commented Oct 9, 2024

@patrickhartling you can point to this using your Gemfile and it'll work in the meantime.
My feeling is a low chance of approval on this tbh, especially since it's not complete support.

@orta
Copy link
Member

orta commented Oct 11, 2024

Anyone in the community can take over this PR if you want it merged, start a fork from the head commit on this branch and go through the feedback in the chat and then send a separate PR - Brett got a lot of the way there, and that's a good job but it doesn't have to be on them to wrap it up

@igor-makarov
Copy link
Contributor

I agree - @Brett-Best did a great job putting together this PR and there's not much left!

There are just a few more attributes to add, I think all of those are simple value types:

  • Copy attributes from PBXGroup to PBXFileSystemSynchronizedRootGroup: name, uses_tabs, indent_width, tab_width, wraps_lines
  • Add new attributes to PBXFileSystemSynchronizedRootGroup:
    • explicit_file_types (type Hash)
    • explicit_folders (type Array)
  • Add new attributes to PBXFileSystemSynchronizedBuildFileExceptionSet:
    • public_headers (type Array)
    • private_headers (type Array)
    • additional_compiler_flags_by_relative_path (type Hash)
    • attributes_by_relative_path (type Hash)

@Brett-Best
Copy link
Contributor Author

Replied to thread above, but one of the things that also needs done, which seems much more complicated is tuist/XcodeProj#852.

I also checked the box to allow: users with write access to CocoaPods/Xcodeproj can add new commits to your feature/Xcode-16.0-Support branch.

@Harry-KNIGHT
Copy link

Hi, any news on this PR ?

@gui17aume
Copy link

I made a new PR based on this one to add some missing attributes: #985

Hoping it will help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.